﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PaperRenderingInterfaces;
using System.ComponentModel.Composition;
using DeepZoomPivotConstructor.PivotLib;
using HtmlAgilityPack;
using PaperPluginUtilities;

namespace CDFPreliminaryResults
{
    /// <summary>
    /// Scan the QCD page. THis is "funny" because it links to sub-pages which then
    /// link to the pages below that. Also, the wya it does published vs other things is
    /// really nice - but different.
    /// </summary>
    [Export(typeof(IPaperRender))]
    [PaperRender("CDFPrelimQCDIndexPage")]
    public class ScanQCDIndexPage : IPaperRender
    {
        [Import]
        IWebAccess WebGetter;

        [Import]
        IPaperRenderEngine MyPaperEngine;

        /// <summary>
        /// Scan the QCD web pages, and for each one we find, load the sub-web page to get
        /// the actual web page with the proper information.
        /// </summary>
        /// <param name="renderAddress"></param>
        /// <returns></returns>
        public IEnumerable<PivotImage> Render(string renderAddress)
        {
            ///
            /// Fetch the page and load it in as an html document.
            /// 

            Uri mainIndexPage = new Uri(renderAddress);
            HtmlDocument doc = new HtmlDocument();
            doc.LoadHtml(WebGetter.GetUriAsString(mainIndexPage));

            ///
            /// Now, we want to scan for every single link in there - but stop when we see the Published
            /// guy!
            /// 

            var results = new EnumerableWrapper<HtmlNode>(doc.DocumentNode.SelectNodes("//*")).TakeWhile(node => node.Name != "center" || node.InnerText.CleanHTMLText() != "Published");

            var links = from l in results
                        where l.Name == "a" && l.Attributes["href"] != null
                        let u = new Uri(mainIndexPage, l.Attributes["href"].Value)
                        where !l.Attributes["href"].Value.StartsWith("#")
                        where u.OriginalString.StartsWith("http://www-cdf.fnal.gov/physics/new/qcd/abstracts")
                        select u;

            return links.SelectMany(ProcessLink);
        }

        /// <summary>
        /// Process the link to the QCD abstract page
        /// </summary>
        /// <param name="htmlAttribute"></param>
        /// <returns></returns>
        private IEnumerable<PivotImage> ProcessLink(Uri abstractWebPage)
        {
            ///
            /// Fetch the page and load it in as an html document.
            /// 

            HtmlDocument doc = new HtmlDocument();
            doc.LoadHtml(WebGetter.GetUriAsString(abstractWebPage));

            ///
            /// Extract a title. We do this incase the page that is referenced ("Web Page" below) doesn't
            /// have a title associated with it
            /// 

            var tables = doc.DocumentNode.SelectNodes("//td");
            string alternateTitle = null;
            if (tables.Count > 2)
            {
                var titleTable = tables[1];
                alternateTitle = titleTable.InnerText.CleanHTMLText();
                if (alternateTitle == null || alternateTitle.Length == 0)
                    alternateTitle = null;
            }

            ///
            /// Now, find the Web Page link, and then run the rendering on that
            /// 

            var links = new EnumerableWrapper<HtmlNode>(doc.DocumentNode.SelectNodes("//a[@href]"));
            var pictures = links.Where(l => l.InnerText.CleanHTMLText() == "Web Page").SelectMany(l =>
                {
                    Uri local = new Uri(abstractWebPage, l.Attributes["href"].Value);
                    return MyPaperEngine.Render("HTMLPlotPage", local.OriginalString)
                        .Apply(img =>
                        {
                            if (alternateTitle != null && !img.Any(md => md.Name == "Note Title"))
                                img.Add("Note Title", alternateTitle);
                        });
                });

            return pictures;
        }
    }
}
